/*
 *    Copyright (c) 2018-2025, boss All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the boss developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: boss
 */
package com.hopes.bizz.risk.hid.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hopes.bizz.risk.common.constant.HidDicConstant;
import com.hopes.bizz.risk.hid.bo.HidChecklistTaskBO;
import com.hopes.bizz.risk.hid.bo.HidTaskNumberProducerBO;
import com.hopes.bizz.risk.hid.dto.HidChecklistTaskDTO;
import com.hopes.bizz.risk.hid.dto.RiskHidCheckTaskDTO;
import com.hopes.bizz.risk.hid.entity.RiskHidCheckContentConfigEntity;
import com.hopes.bizz.risk.hid.entity.RiskHidCheckTaskEntity;
import com.hopes.bizz.risk.hid.entity.RiskHidCheckTaskRecordEntity;
import com.hopes.bizz.risk.hid.mapper.RiskHidCheckTaskMapper;
import com.hopes.bizz.risk.hid.service.RiskHidCheckContentConfigService;
import com.hopes.bizz.risk.hid.service.RiskHidCheckTaskRecordService;
import com.hopes.bizz.risk.hid.service.RiskHidCheckTaskService;
import com.hopes.boss.common.core.exception.BizException;
import com.hopes.boss.common.security.util.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 隐患检查任务
 *
 * @author pig
 * @date 2023-07-25 17:24:15
 */
@Service
@RequiredArgsConstructor
public class RiskHidCheckTaskServiceImpl extends ServiceImpl<RiskHidCheckTaskMapper, RiskHidCheckTaskEntity> implements RiskHidCheckTaskService {

    private final RiskHidCheckTaskRecordService riskHidCheckTaskRecordService;

    private final RiskHidCheckContentConfigService riskHidCheckContentConfigService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean completeTask(HidChecklistTaskDTO checklistTaskDTO) {
        // 1、更新检查项
        final List<HidChecklistTaskBO> checklistTaskItemList = checklistTaskDTO.getChecklistTaskItemList();
        Assert.notEmpty(checklistTaskItemList, "完成的检查任务项不可为空！");

        final Date time = Calendar.getInstance().getTime();
        final Long userId = SecurityUtils.getUser().getId();
        final ArrayList<RiskHidCheckTaskRecordEntity> riskHidCheckTaskRecordList = new ArrayList<>();

        for (HidChecklistTaskBO hidChecklistTaskBO : checklistTaskItemList) {
            final RiskHidCheckTaskRecordEntity riskHidCheckTaskRecordEntity = new RiskHidCheckTaskRecordEntity();
            BeanUtils.copyProperties(hidChecklistTaskBO, riskHidCheckTaskRecordEntity);
            riskHidCheckTaskRecordEntity.setCheckDate(time);
            riskHidCheckTaskRecordEntity.setCheckUserId(userId);

            riskHidCheckTaskRecordList.add(riskHidCheckTaskRecordEntity);
        }
        riskHidCheckTaskRecordService.updateBatchById(riskHidCheckTaskRecordList);

        // 2、更新任务状态和结论
        final RiskHidCheckTaskEntity riskHidCheckTask = new RiskHidCheckTaskEntity();
        riskHidCheckTask.setId(checklistTaskDTO.getId());
        riskHidCheckTask.setTotalNum(checklistTaskItemList.size());
        final Map<Integer, List<HidChecklistTaskBO>> groupMap = checklistTaskItemList.stream().collect(Collectors.groupingBy(HidChecklistTaskBO::getConclusion));
        final List<HidChecklistTaskBO> passList = groupMap.get(HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_NORMAL);
        final List<HidChecklistTaskBO> exList = groupMap.get(HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_EXCEPTION);

        riskHidCheckTask.setPassNum(Optional.ofNullable(passList).map(List::size).orElse(0));
        riskHidCheckTask.setNotPassNum(Optional.ofNullable(exList).map(List::size).orElse(0));
        riskHidCheckTask.setFinishDate(time);
        riskHidCheckTask.setHandleId(userId);
        riskHidCheckTask.setRecorderSignature(checklistTaskDTO.getRecorderSignature());
        riskHidCheckTask.setCheckPersonSignature(checklistTaskDTO.getCheckPersonSignature());
        riskHidCheckTask.setTaskConclusion(riskHidCheckTask.getNotPassNum() > 0 ? HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_EXCEPTION : HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_NORMAL);

        // 所有任务项都完成， 任务完成
        final long count = riskHidCheckTaskRecordService.count(
                Wrappers.<RiskHidCheckTaskRecordEntity>lambdaQuery().eq(RiskHidCheckTaskRecordEntity::getTaskId, checklistTaskDTO.getId()));
        if (count == checklistTaskItemList.size()) {
            riskHidCheckTask.setTaskStatus(HidDicConstant.RISK_HID_CHECKLIST_TASK_STATUS_COMPLETE);
        }
        return baseMapper.updateById(riskHidCheckTask) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveTask(RiskHidCheckTaskDTO riskHidCheckTask) {
        // 校验
        Date startTime = riskHidCheckTask.getStartTime();
        Date deadline = riskHidCheckTask.getDeadline();
        if (DateUtil.compare(startTime, deadline) > 0) {
            throw new BizException("保存任务失败,开始时间不能大于截止时间!");
        }
        // 构建task并保存
        RiskHidCheckTaskEntity task = new RiskHidCheckTaskEntity();
        BeanUtils.copyProperties(riskHidCheckTask, task);
        task.setTaskStatus(HidDicConstant.RISK_HID_CHECKLIST_TASK_STATUS_TODO);
        task.setTaskConclusion(HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_NOT_CHECKED);
        final RiskHidCheckTaskEntity checkTaskEntity = getOne(
                Wrappers.<RiskHidCheckTaskEntity>lambdaQuery()
                        .select(RiskHidCheckTaskEntity::getTaskNo)
                        .orderByDesc(RiskHidCheckTaskEntity::getTaskNo).last("limit 1"));
        HidTaskNumberProducerBO producer = new HidTaskNumberProducerBO(Optional.ofNullable(checkTaskEntity).map(RiskHidCheckTaskEntity::getTaskNo).orElse(null));
        List<String> hidCheckListConfigId = riskHidCheckTask.getHidCheckListConfigIdList();
        task.setTaskNo(producer.getTaskNo());
        task.setHidCheckListConfigId(String.join(",", hidCheckListConfigId));
        task.setRiskUnitId(String.join(",", riskHidCheckTask.getRiskUnitIdList()));
        if (CollectionUtil.isNotEmpty(hidCheckListConfigId)) {
            final List<RiskHidCheckContentConfigEntity> contentConfigs = riskHidCheckContentConfigService.list(Wrappers.<RiskHidCheckContentConfigEntity>lambdaQuery().in(RiskHidCheckContentConfigEntity::getRiskHidCheckListConfigId, hidCheckListConfigId));
            task.setTotalNum(contentConfigs.size());
            this.save(task);
            final List<RiskHidCheckTaskRecordEntity> collect = contentConfigs.stream().map(item -> {
                final RiskHidCheckTaskRecordEntity record = new RiskHidCheckTaskRecordEntity();
                record.setWay(item.getWay());
                record.setItem(item.getItem());
                record.setBasis(item.getBasis());
                record.setContent(item.getContent());
                record.setTaskId(task.getId());
                record.setRiskHidCheckContentConfigId(item.getId());
                record.setRiskHidCheckListConfigId(item.getRiskHidCheckListConfigId());
                record.setConclusion(HidDicConstant.RISK_HID_CHECKLIST_TASK_CONCLUSION_NOT_CHECKED);
                return record;
            }).collect(Collectors.toList());
            riskHidCheckTaskRecordService.saveBatch(collect);
        }

    }
}
